//Module Mixin;

/**************************
 *  Autor: Lukasz Kufel   *
 *  Przedmiot: Jezyk D    *
 *     zadanie nr 6       *
 * "W trakcie kompilacji" *
 **************************/

import tango.io.Stdout;

template silnia(int n){
	static if (n == 0){
		const int siln = 1;
	} else {
		const int siln = silnia!(n-1).siln * n;
	}
}

template fib(int n){
	static if (n == 0) {
		const int liczba = 0;
		const int[] tab = [0];
	} else static if (n == 1) {
		const int liczba = 1;
		const int[] tab = fib!(n-1).tab ~ liczba;
	} else {
		const int liczba = fib!(n-1).liczba + fib!(n-2).liczba;
		const int[] tab = fib!(n-1).tab ~ liczba;
	}
}

template ackermann(int m, int n){
	static if(m == 0) {
		const int ack = n + 1;
	} else static if (m > 0 && n == 0) {
		const int ack = ackermann!(m - 1, 1).ack;
	} else static if (m > 0 && n > 0) {
		const int ack = ackermann!(m - 1, ackermann!(m, n - 1).ack).ack;
	}
}

void main() {
	mixin silnia!(5);
	Stdout.formatln("silnia(5) = {}", siln);
	
	mixin fib!(30);
	Stdout.formatln("fib(12) = {}, tab = {}", liczba, tab);
	
	//Sprawdzenie
	for(int i = 2; i < tab.length; i++){
		assert(tab[i] == tab[i-1] + tab[i-2]);
	}
	
	mixin ackermann!(3,4);
	Stdout.formatln("ackermann(5) = {}", ack);
}